﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using SaiLing.Domain.Persistence.Relational;

namespace SaiLing.SingleSignOn.Domain.Entities.System
{
    public class Module : IEntity
    {
        public string Name { get; set; }

        public string Area { get; set; }

        public string ExecController { get; set; }

        public string ExecAction { get; set; }

        public string Icon { get; set; }

        public string Background { get; set; }

        public Guid ParentId { get; set; }

        public bool Visible { get; set; } = true;

        public int Sort { get; set; }

        public Guid AppId { get; set; }

        public virtual Application App { get; set; }

        public virtual List<ModuleAction> Actions { get; set; }

        /// <summary>
        /// 子菜单集合
        /// </summary>
        public virtual IEnumerable<Module> ChildrenList { get; set; }

        
        public int? Level { get; set; } = 0;
    }

    public static class ModuleExtensions
    {
        public static IEnumerable<Module> ToTreeList(this IEnumerable<Module> source)
        {
            if (source != null)
            {
                var rootList = source.Where(x => x.ParentId == Guid.Empty).ToList().OrderBy(x => x.Sort);
                foreach (var root in rootList)
                {
                    root.ChildrenList = source.Where(x => x.ParentId == root.Id).OrderBy(x => x.Sort);
                }
                return rootList;
            }
            return null;
        }

        public static List<Module> ToTreeList(this IEnumerable<Module> source, List<Module> result, Guid? parentId = null)
        {
            if (source == null)
                return null;
            result = result ?? new List<Module>();
            parentId = parentId ?? Guid.Empty;
            var root = source.Where(x => x.ParentId == parentId).OrderBy(x => x.Sort).ToList();
            if (!root.Any())
                return result;
            foreach (var item in root)
            {
                item.Level = item.ParentId == Guid.Empty ? 1 : item.Level;
                SetChildren(source, item);
                result.Add(item);
            }
            return result;
        }

        public static void SetChildren(IEnumerable<Module> source, Module item)
        {
            if (item != null && source != null && source.Any())
            {
                var children = source.Where(x => x.ParentId == item.Id).OrderBy(x => x.Sort).ToList();
                if (children.Any())
                {
                    children.ForEach(x =>
                    {
                        x.Level = item.Level + 1;
                        SetChildren(source, x);
                    });
                    item.ChildrenList = children;
                }
            }
        }

        public static List<dynamic> ToPermssionTreeList(this IEnumerable<Module> source, List<dynamic> result, List<Permission> permissions, Guid? parentId = null)
        {
            if (source == null)
                return null;
            result = result ?? new List<dynamic>();
            parentId = parentId ?? Guid.Empty;
            var root = source.Where(x => x.ParentId == parentId).ToList();
            if (!root.Any())
                return result;
            foreach (var item in root)
            {
                SetPermssionChildren(source, item, permissions);
                result.Add(item);
            }
            return result;
        }

        public static void SetPermssionChildren(IEnumerable<Module> source, Module item, List<Permission> permissions)
        {
            if (item != null && source != null && source.Any())
            {
                var children = source.Where(x => x.ParentId == item.Id).ToList();
                if (children.Any())
                {
                    children.ForEach(x =>
                    {
                        SetPermssionChildren(source, x, permissions);
                    });
                    item.ChildrenList = children;
                }
                else
                {
                    item.Actions = item.Actions.ToList();
                }
            }
        }
    }

    public class ModuleEqualityComparer : IEqualityComparer<Module>
    {
        bool IEqualityComparer<Module>.Equals(Module x, Module y)
        {
            return x.Id == y.Id;
        }

        int IEqualityComparer<Module>.GetHashCode(Module obj)
        {
            return obj.Id.GetHashCode();
        }
    }
}